use crate::image::ImageSegmentator;
use crate::prequire::{
  adb::{screenshot::ScreenshotCmd, shell::ShellCmd},
  BinaryCommand,
};
use crate::project::catcher::{CatchOptions, Catcher};
use crate::project::conf::project_conf::ProjectConf;
use anyhow::{anyhow, Result};
use indicatif::ProgressBar;
use std::fs::rename;
use std::path::Path;
use std::path::PathBuf;
use std::thread;

pub struct KeywordAutoSearchCatcher<'a> {
  conf: &'a ProjectConf,
}

impl<'a> KeywordAutoSearchCatcher<'a> {
  pub fn new(conf: &'a ProjectConf) -> Self {
    KeywordAutoSearchCatcher { conf }
  }
}

impl<'a> Catcher for KeywordAutoSearchCatcher<'a> {
  fn screenshot<P: AsRef<Path>>(
    &self,
    out_dir: P,
    num: u64,
    opts: &CatchOptions,
  ) -> Result<Vec<String>> {
    self.ensure_out_dir(out_dir.as_ref());
    let out_raw_dir = self.ensure_out_raw_dir(out_dir.as_ref());
    let (m, sty) = self.create_indicator();

    // pb负责从设备截图到本地
    let pb = m.add(ProgressBar::new(num));
    pb.set_style(sty.clone());
    // pb2负责将一页图分割
    let pb2 = m.insert_after(&pb, ProgressBar::new(num));
    pb2.set_style(sty);

    let capture_section = self
      .conf
      .app
      .get_page("search")
      .unwrap()
      .get_capture()
      .unwrap();
    let segment_border_color = capture_section.segment_border_color.to_rgba();
    let segment_sample_size = capture_section.segment_sample_size.to_u32();
    let segment_left_padding = capture_section.segment_left_padding.to_u32();
    let segment_right_padding = capture_section.segment_right_padding.to_u32();
    let segment_left_crop = capture_section.segment_left_crop.to_u32();
    let segment_right_crop = capture_section.segment_right_crop.to_u32();
    let segment_min_height = capture_section.segment_min_height.to_u32();
    let segment_max_height = capture_section.segment_max_height.to_u32();

    m.println("开始处理!").unwrap();

    let capture = self
      .conf
      .app
      .get_page("search")
      .ok_or(anyhow!("not found page <search>"))?
      .get_capture()
      .ok_or(anyhow!("not found capture section on page <search>"))?;

    // let swipe_from = capture.swipe_from.shell_args();
    // let swipe_to = capture.swipe_to.shell_args();
    let swipe_duration = capture.swipe_duration.shell_args();

    let capture_dir = out_dir.as_ref().to_path_buf();
    let m_clone = m.clone();
    let h1 = thread::spawn(move || {
      let capacity: usize = (num * 5).try_into().unwrap();
      let mut segments = Vec::with_capacity(capacity);
      for i in 0..num {
        pb.set_message(format!("屏幕截取 item #{}", i + 1));
        let out = format!("{}/{}.png", capture_dir.display(), i);
        // use adb take screenshot
        if let Err(err) = ScreenshotCmd::new(out).exec() {
          eprintln!("截图失败!\n{}", err);
          m_clone.println("截图失败!").unwrap();
          pb.abandon_with_message("中止");
          return segments;
        }
        pb.inc(1);

        pb2.set_message(format!("separate item #{}", i + 1));
        // use adb binarization image
        let src_file_name = format!("{}.png", i);
        let src_file_path = format!("{}/{}", capture_dir.display(), &src_file_name);

        println!("src png =>{}", src_file_path);

        if let Ok((files, top_splitter, bottom_splitter)) =
          ImageSegmentator::new(PathBuf::from(&src_file_path))
            .set_boudary_color(segment_border_color)
            .set_sampling_size(segment_sample_size)
            .set_left_padding(segment_left_padding)
            .set_right_padding(segment_right_padding)
            .set_left_crop(segment_left_crop)
            .set_right_crop(segment_right_crop)
            .set_min_height(segment_min_height)
            .set_max_height(segment_max_height)
            .split_save()
        {
          segments.extend(files);
          rename(src_file_path, out_raw_dir.join(src_file_name)).expect("failed rename src");
          let swipe_from = format!("600 {}", bottom_splitter);
          let swipe_to = format!("600 {}", top_splitter);
          println!("swipe from({}) -> to({})", &swipe_from, &swipe_to);
          if let Err(err) = ShellCmd::new(
            &["input swipe", &swipe_from, &swipe_to, &swipe_duration],
            Some(Box::new(|_| String::from(""))),
          )
          .exec()
          {
            eprintln!("滚动失败!\n{}", err);
            continue;
          }

          println!("done!");
        } else {
          eprintln!("can't split image!");
        };
        pb2.inc(1);
      }
      m_clone.println("截图完成!").unwrap();
      pb.finish_with_message("成功");
      pb2.finish_with_message("成功");
      segments
    });

    // let _ = h1.join();
    let r = h1.join().unwrap_or(vec![]);
    m.clear().unwrap();

    Ok(r)
  }
}
